package top.zhangjianyong.utils;

import cn.hutool.core.collection.CollectionUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import top.zhangjianyong.entity.ReptileUrl;

import java.sql.SQLException;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author ： zhangjianyong
 * @date ： 2023/3/23 3:38 PM
 */
@Slf4j
public class ReptileContent {

    public static void init() throws SQLException {
        log.info("重置状态处理中");

        int update1 = JDBCUtil.update("insert into reptile_url(id,url,host,from_url,remark,state,create_time,update_time) " +
                "select id,url,host,from_url,remark,0,create_time,update_time from reptile_url_wait");
        int update2 = JDBCUtil.update("DELETE FROM reptile_url_wait");
        if (update2 != update1) {
            throw new RuntimeException("重置数量不一致");
        }
        //JDBCUtil.commit();
    }

    /**
     * 添加网页地址
     *
     * @param url
     * @return
     */
    public static void offerUrl(String url, String from) throws SQLException {
        if (StringUtils.isEmpty(url)) {
            return;
        }
        if (exists(url)) return;

        log.info("加入网页地址队列地址： {}", url);
        addUrl(url, UrlUtil.reveresHost(url), UrlUtil.host(from));
    }


    /**
     * 添加网页地址
     *
     * @param list
     */
    public static void offerUrl(Set<String> list, String from) throws SQLException {
        for (String url : list) {
            offerUrl(url, from);
        }
    }


    /**
     * 取出网页地址并移除
     *
     * @return
     */
    public static ReptileUrl pollUrl() throws SQLException {
        Map<String, Object> map = JDBCUtil
                .qryObj("select URL from reptile_url where state=0 ORDER BY create_time limit 1");
        return new ReptileUrl(map);
    }

    public static List<ReptileUrl> pollUrl(int limit) throws SQLException {
        List<Map<String, Object>> maps = JDBCUtil.qryList(
                "SELECT ID,URL from reptile_url ORDER BY create_time limit ?", limit);

        return maps.stream().map(map -> new ReptileUrl(map)).collect(Collectors.toList());
    }


    /**
     * 修改网页状态
     *
     * @param url     网址
     * @param process 状态 0-初始，1-错误，2-成功，3-重定向，4-无法访问
     * @throws SQLException
     */
    public static void visitUrl(String url, int process) throws SQLException {

        JDBCUtil.update("update reptile_url set state=?,update_time=? where url=?", process, LocalDateTime.now(), url);
    }


    public static void addUrl(String url, String host, String from) throws SQLException {
        JDBCUtil.update("insert ignore into reptile_url(url,host,from_url,state) values(?,?,?,?)", url, host, from, 0);
    }


    public static boolean isEmptyUrl() throws SQLException {

        Map<String, Object> map = JDBCUtil.qryObj("select 1 as count from reptile_url limit 1");
        Long count = (Long) map.get("count");
        return count == 0;
    }

    public static boolean isNotEmptyUrl() throws SQLException {
        return !isEmptyUrl();
    }

    public static int updateHead(ReptileUrl reptileUrl, HtmlUtil.HtmlHead head) throws SQLException {
        String sql = "update reptile_url_wait set remark=? where id=? ";
        StringBuilder sb = new StringBuilder();
        sb.append(head.title).append("\n")
                .append(head.keywords).append("\n")
                .append(head.description).append("\n");
        return JDBCUtil.update(sql, sb.toString(), reptileUrl.getId());
    }

    public static long waitCount() throws SQLException {
        Map<String, Object> map = JDBCUtil.qryObj("select count(1) as count from reptile_url_wait ");
        Long count = (Long) map.get("count");
        return count;
    }

    public static boolean isWait(int threshold) throws SQLException {
        long waitCount = waitCount();
        return waitCount > threshold;
    }

    public static void waitUrl(ReptileUrl url) throws SQLException {
        moveData("reptile_url", "reptile_url_wait", url.getId(), 1);
    }

    public static void initUrl(ReptileUrl url) throws SQLException {
        moveData("reptile_url_wait", "reptile_url", url.getId(), 0);
    }

    public static void sucUrl(ReptileUrl url, int process) throws SQLException {
        moveData("reptile_url_wait", "reptile_url_suc", url.getId(), process);
    }

    public static void errUrl(ReptileUrl url, int process) throws SQLException {
        moveData("reptile_url_wait", "reptile_url_err", url.getId(), process);
    }

    public static void moveData(String from, String to, Long id, int process) throws SQLException {

        int update1 = JDBCUtil.update("INSERT into " + to + " (id,url,host,from_url,remark,state,create_time,update_time)" +
                        "SELECT id,url,host,from_url,remark,? as state,create_time,? from " + from + " WHERE id = ?",
                process, LocalDateTime.now(), id);
        int update2 = JDBCUtil.update("delete from " + from + " where id =?", id);
        if (update1 != update2) {
            throw new RuntimeException("等待更新数量错误");
        }
        //JDBCUtil.commit();

    }

    public static List<ReptileUrl> listByUrl(String url) throws SQLException {
        List<Map<String, Object>> maps = JDBCUtil.qryList("select * from reptile_url where url =? ", url);
        return maps.stream().map(map -> new ReptileUrl(map)).collect(Collectors.toList());
    }

    public static List<ReptileUrl> listSucByUrl(String url) throws SQLException {
        List<Map<String, Object>> maps = JDBCUtil.qryList("select url from reptile_url_suc where url =? ", url);
        return maps.stream().map(map -> new ReptileUrl(map)).collect(Collectors.toList());
    }

    public static List<ReptileUrl> listErrByUrl(String url) throws SQLException {
        List<Map<String, Object>> maps = JDBCUtil.qryList("select url from reptile_url_err where url =? ", url);
        return maps.stream().map(map -> new ReptileUrl(map)).collect(Collectors.toList());
    }

    public static List<ReptileUrl> listWaitByUrl(String url) throws SQLException {
        List<Map<String, Object>> maps = JDBCUtil.qryList("select url from reptile_url_wait where url =? ", url);
        return maps.stream().map(map -> new ReptileUrl(map)).collect(Collectors.toList());
    }

    public static int delErr(Long id) throws SQLException {
        return JDBCUtil.update("delete from reptile_url_err where id =?", id);
    }

    public static int delSuc(Long id) throws SQLException {
        return JDBCUtil.update("delete from reptile_url_suc where id =?", id);
    }

    public static int del(Long id) throws SQLException {
        return JDBCUtil.update("delete from reptile_url where id =?", id);
    }

    public static boolean exists(ReptileUrl reptileUrl) throws SQLException {
        return exists(reptileUrl.getUrl());
    }

    public static boolean exists(String url) throws SQLException {
        List<ReptileUrl> sucByUrl = listSucByUrl(url);
        if (CollectionUtil.isNotEmpty(sucByUrl)) {
            return true;
        }

        List<ReptileUrl> errByUrl = listErrByUrl(url);
        if (CollectionUtil.isNotEmpty(errByUrl)) {
            return true;
        }
        List<ReptileUrl> waitByUrl = listWaitByUrl(url);
        if (CollectionUtil.isNotEmpty(waitByUrl)) {
            return true;
        }
        return false;
    }
}
